import { Controller, Get, Param, BadGatewayException, Req, UseInterceptors, Redirect, Headers, Res, Post, Body } from '@nestjs/common';
import { InjectModel } from 'nestjs-typegoose';
import { ModeEnum, Qrcode, TypeEnum } from '@libs/db/models/qrcode.models';
import { ModelType } from '@typegoose/typegoose/lib/types';
import { Subcode } from '@libs/db/models/subcode.models';
import { IP } from '@libs/db/models/ip.models';
import { DisturInterceptor } from './distur.interceptor';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { GetSpot } from '../subcode/dto/getqrcodeone.dto';
import { renderFile } from 'ejs';
import { resolve } from 'path';

@ApiTags('活码url')
@Controller()

export class DisturlController {
    constructor(
        private DisturInterceptor: DisturInterceptor,
        @InjectModel(Qrcode) private qrcodeModel: ModelType<Qrcode>,
        @InjectModel(Subcode) private SubcodeModel: ModelType<Subcode>,
        @InjectModel(IP) private IPModel: ModelType<IP>
    ) { }

    @ApiOperation({ summary: "主活码api" })
    @UseInterceptors(DisturInterceptor)
    @Get("/:shortid")
    async disturl(@Param() param, @Req() req, @Res() res, @Headers("user-agent") header) {
        //查询主活码
        const qrcode = await this.qrcodeModel.findOne({ ...param })

        // 要显示的子码信息
        const subcode: Subcode = await this.displaymode(qrcode.displaymode, qrcode)
        // //达到做大值,关闭二维码
        if (subcode.restrictedmode <= 1) {
            this.SubcodeModel.updateOne({ _id: subcode._id }, { status: false }).then()
        }

        // 添加ip信息
        const time = Math.floor(Date.now() / 1000)
        const ip = this.DisturInterceptor.getip(req)
        const usercity = await this.DisturInterceptor.ipmap(ip)
        if (qrcode.displaylimit) {
            await this.IPModel.create({ ip, subcodeid: subcode._id, time, usercity, qrcode: qrcode._id, userid: subcode.userid })
        } else {
            const res = await this.IPModel.findOne({ ip, subcodeid: subcode._id })
            if (res) {
                await this.IPModel.updateOne({ _id: res._id, subcodeid: subcode._id }, { $inc: { sum: 1 }, time: Math.floor(Date.now() / 1000) })
            } else {
                await this.IPModel.create({ ip, subcodeid: subcode._id, time, usercity, qrcode: qrcode._id, userid: subcode.userid })
            }
        }

        //修改子码数据
        await this.SubcodeModel.updateOne({ _id: subcode._id }, { $inc: { impression: 1, identifynum: 1, restrictedmode: -1 } })
        //修改活码数据
        await this.qrcodeModel.updateOne({ _id: qrcode._id }, { $inc: { todayscann: 1, totalscann: 1 } })


        let versions = this.DisturInterceptor.versions(header);
        let url: string = subcode.suburl
        if (versions.ios) {
            if (!versions.weixin) {
                if (qrcode.types === TypeEnum.QQ) {
                    url = `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${subcode.originalname}&card_type=person&source=qrcode`
                } else {
                    url = 'weixin://'
                }
            }
        } else {
            if (qrcode.types != TypeEnum.QQ) {
                url = 'weixin://'
            }
        }
        switch (qrcode.mode) {
            case ModeEnum.url:
                return res.redirect(url);
            case ModeEnum.json:
                return res.send({
                    url,
                    name: subcode.originalname,
                    path: subcode.path,
                    id: subcode._id,
                    type: qrcode.types
                })

            case ModeEnum.view:
                const data = await renderFile(`${resolve()}/public/views/index.ejs`, {
                    url,
                    name: subcode.originalname,
                    path: subcode.path,
                    id: subcode._id,
                    type: qrcode.types
                });
                res.writeHead(200, { 'Content-Type': 'text/html' });
                return res.end(data);
        }
    }


    @ApiOperation({ summary: "点击量api" })
    @Post("click")
    async Identify(@Body() body: GetSpot): Promise<object> {
        const subip: IP = await this.IPModel.findOne({ subcodeid: body.id })
        if (!subip.onClick) {
            const subcode: Subcode = await this.SubcodeModel.findOne({ _id: body.id })
            this.IPModel.updateOne({ _id: subip._id }, { onClick: true }).then()
            this.SubcodeModel.updateOne({ _id: body.id }, { $inc: { todayclick: 1, totalclick: 1 } }).then()
            this.qrcodeModel.updateOne({ _id: subcode.qrcodeid }, { $inc: { todayclick: 1, totalclick: 1 } }).then()
            return { msg: 'ok' }
        }
        return { msg: 'no' }
    }


    //显示模式 true:逐个显示模式,false:随机显示模式
    private async displaymode(condition, qrcode): Promise<Subcode> {
        if (!condition) {
            const count: number = await this.SubcodeModel.estimatedDocumentCount({})
            const random: number = Math.floor(Math.random() * count)
            const subcode: Subcode = await this.SubcodeModel.findOne({ qrcodeid: qrcode._id, status: true }).skip(random).limit(1)
            if (!subcode) throw new BadGatewayException("没有可用子码")
            return subcode
        } else {
            const subcode = await this.SubcodeModel.findOne({ qrcodeid: qrcode._id, status: true }).sort({ identifynum: 1 })
            if (!subcode) throw new BadGatewayException("没有可用子码")
            return subcode
        }
    }
}
